home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 3 / Info_Mac_1994-01.iso / Development / Source / IRC client Source / ircle sources / IRCCommands.p < prev    next >
Encoding:
Text File  |  1993-07-19  |  9.6 KB  |  431 lines  |  [TEXT/PJMM]

  1. {    ircle - Internet Relay Chat client    }
  2. {    File: IRCCommands    }
  3. {    Copyright © 1992 Olaf Titz (s_titz@ira.uka.de)    }
  4.  
  5. {    This program is free software; you can redistribute it and/or modify    }
  6. {    it under the terms of the GNU General Public License as published by    }
  7. {    the Free Software Foundation; either version 2 of the License, or    }
  8. {    (at your option) any later version.    }
  9.  
  10. {    This program is distributed in the hope that it will be useful,    }
  11. {    but WITHOUT ANY WARRANTY; without even the implied warranty of    }
  12. {    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    }
  13. {    GNU General Public License for more details.    }
  14.  
  15. {    You should have received a copy of the GNU General Public License    }
  16. {    along with this program; if not, write to the Free Software    }
  17. {    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.    }
  18.  
  19. unit IRCCommands;
  20. { Handles commands typed in by the user }
  21.  
  22. interface
  23. uses
  24.     TCPTypes, TCPStuff, TCPConnections, ApplBase, MsgWindows, {}
  25.     IRCGlobals, IRCaux, IRCPreferences, IRCChannels, IRCHelp, {}
  26.     IRCNotify, IRCIgnore, DCC;
  27.  
  28. var
  29.     listmin, listmax: integer;
  30.     listpub, listpriv, listloc, listglob, listtop: boolean;     { Flags for /list display }
  31.  
  32. procedure HandleCommand (var s: string);
  33. { Process s as command line }
  34.  
  35. procedure sendCTCP (var t, s: string);
  36. { send CTCP message }
  37.  
  38. procedure RegUser;
  39. { Send the server the first commands to register the user }
  40.  
  41. implementation
  42.  
  43. { This procedure is to be run in the background, to type }
  44. { a file to the current channel. }
  45. procedure TypeCmd;
  46.     var
  47.         s, t: Str255;
  48.         f: text;
  49.     begin
  50.         t := CurrentTarget;
  51.         if t <> '' then begin
  52.             s := OldFileName(concat('Type to ', t, ':'));
  53.             if s <> '' then begin
  54.                 reset(f, s);
  55.                 s := concat('*** Typing ', s, '...');
  56.                 ChannelMsg(t, s);
  57.                 while not eof(f) do begin
  58.                     if flushing then begin
  59.                         flushing := false;
  60.                         leave;
  61.                     end;
  62.                     readln(f, s);
  63.                     if s <> '' then begin
  64.                         s := concat('PRIVMSG ', t, ' :', s);
  65.                         PutLine(s);
  66.                     end
  67.                 end;
  68.                 close(f);
  69.                 s := '*** Finished  TYPE';
  70.                 ChannelMsg(t, s);
  71.             end;
  72.         end
  73.     end;
  74.  
  75. procedure ParseComLine (var l: string; var com: str255; var rest: string);
  76.     var
  77.         i: integer;
  78.         c: char;
  79.     begin
  80.         if l[1] = cmdChar then
  81.             delete(l, 1, 1);
  82.         i := pos(' ', l);
  83.         if i = 0 then begin
  84.             com := copy(l, 1, 255);
  85.             rest := ''
  86.         end
  87.         else begin
  88.             com := copy(l, 1, i - 1);
  89.             while (i <= length(l)) and (l[i] = ' ') do
  90.                 i := succ(i);
  91.             rest := copy(l, i, 255)
  92.         end;
  93.         UprString(com, false);
  94.     end;
  95.  
  96. procedure DoServer (var rest: string);
  97.     var
  98.         i: longint;
  99.         s1: string;
  100.     begin
  101.         NextArg(rest, s1);
  102.         if length(s1) > 0 then begin
  103.             case serverStatus of
  104.                 S_LOOKUP, S_OPENING: 
  105.                     begin
  106.                     StatusMsg(E_OPEN);
  107.                     exit(DoServer)
  108.                 end;
  109.                 S_CONN: 
  110.                     CloseConnection(sSocket);
  111.                 otherwise
  112.             end;
  113.             serverConn := s1;
  114.             if length(rest) > 0 then begin
  115.                 StringToNum(rest, i);
  116.                 serverPort := integer(i);
  117.             end;
  118.             repeat
  119.                 ApplRun
  120.             until serverStatus = S_OFFLINE;
  121.             OpenConnection;
  122.             if serverStatus = S_CONN then
  123.                 RegUser;
  124.         end;
  125.     end;
  126.  
  127. function match (var s1: string; s2: str20): boolean;
  128.     var
  129.         i, n: integer;
  130.     begin
  131.         i := length(s1);
  132.         n := length(s2);
  133.         if n > i then
  134.             n := i;
  135.         i := 1;
  136.         while i <= n do begin
  137.             if s1[i] <> s2[i] then begin
  138.                 match := false;
  139.                 exit(match)
  140.             end;
  141.             i := i + 1;
  142.         end;
  143.         match := true;
  144.     end;
  145.  
  146. procedure TranslateCommand (var s: string);
  147. { Translates aliases & processes internal commands }
  148. { Will return an empty string if command already processed }
  149. { Note: valid commands not mentioned here get sent to the server unprocessed anyway. }
  150. { That means that an error message for wrong commands comes always from the server. }
  151.     type
  152.         str8 = string[8];
  153.     var
  154.         com, rest, s1: str255;
  155.         i: integer;
  156.         dd: MWHndl;
  157.     procedure twoargs (com: str8);
  158.         begin
  159.             NextArg(rest, s1);
  160.             s := concat(com, ' ', s1, ' :', rest)
  161.         end;
  162.     function nextnum: integer;
  163.         var
  164.             l: longint;
  165.         begin
  166.             NextArg(rest, s1);
  167.             stringtonum(s1, l);
  168.             nextnum := l
  169.         end;
  170.     procedure join;
  171.         begin
  172.             if rest = '' then
  173.                 rest := lastInvite;
  174.             MakeChannel(rest);
  175.             s := concat('JOIN :', rest);
  176.         end;
  177.     procedure part;
  178.         begin
  179.             MakeChannel(rest);
  180.             s := concat('PART :', rest)
  181.         end;
  182.     procedure signoff;
  183.         begin
  184.             if rest = '' then
  185.                 rest := 'Leaving';
  186.             s := concat('QUIT :', rest);
  187.             QuitRequest := true
  188.         end;
  189.     begin
  190.         ParseComLine(s, com, rest);
  191.         if match(com, 'AWAY') then begin
  192.             IsAway := (rest[0] <> chr(0));
  193.             UpdateStatusLine;
  194.             s := concat('AWAY :', rest);
  195.         end
  196.         else if match(com, 'BROADCAST') then begin
  197.             GetAllWindows(true, true, false, com);
  198.             if com[0] = chr(0) then
  199.                 StatusMsg(E_NOTARGET)
  200.             else begin
  201.                 s := concat('>* ', rest);
  202.                 Message(s);
  203.                 s := concat('PRIVMSG ', com, ' :', rest)
  204.             end
  205.         end
  206.         else if match(com, 'BYE') then
  207.             signoff
  208.         else if match(com, 'CHANNEL') then
  209.             join
  210.         else if match(com, 'CMDCHAR') then begin
  211.             if rest[0] <> chr(0) then
  212.                 cmdChar := rest[1];
  213.             s := ''
  214.         end
  215.         else if match(com, 'CTCP') then begin
  216.             i := pos(' ', rest);
  217.             if i = 0 then begin
  218.                 com := rest;
  219.                 rest := ''
  220.             end
  221.             else begin
  222.                 com := copy(rest, 1, i - 1);
  223.                 delete(rest, 1, i)
  224.             end;
  225.             sendCTCP(com, rest);
  226.             s := ''
  227.         end
  228.         else if match(com, 'DATE') then
  229.             s := concat('TIME ', rest)
  230.         else if match(com, 'DCC') then begin
  231.             DCCcommand(rest);
  232.             s := ''
  233.         end
  234.         else if match(com, 'EXIT') then
  235.             signoff
  236.         else if match(com, 'HELP') then begin
  237.             ShowHelp;
  238.             s := ''
  239.         end
  240.         else if match(com, 'IGNORE') then begin
  241.             DoIgnore(rest);
  242.             s := ''
  243.         end
  244.         else if match(com, 'KICK') then
  245.             twoargs('KICK')
  246.         else if match(com, 'KILL') then
  247.             twoargs('KILL')
  248.         else if match(com, 'JOIN') then
  249.             join
  250.         else if match(com, 'LIST') then begin
  251.             listpub := true;
  252.             listpriv := true;
  253.             listloc := true;
  254.             listglob := true;
  255.             listtop := true;
  256.             listmin := 0;
  257.             listmax := maxint;
  258.             repeat
  259.                 if rest[0] = chr(0) then
  260.                     leave;
  261.                 if rest[1] = '-' then begin
  262.                     NextArg(rest, s1);
  263.                     UprString(s1, false);
  264.                     if s1 = '-MIN' then
  265.                         listmin := nextnum
  266.                     else if s1 = '-MAX' then
  267.                         listmax := nextnum
  268.                     else if match(s1, '-PUBLIC') then
  269.                         listpriv := false
  270.                     else if match(s1, '-PRIVATE') then
  271.                         listpub := false
  272.                     else if match(s1, '-LOCAL') then
  273.                         listglob := false
  274.                     else if match(s1, '-GLOBAL') then
  275.                         listloc := false
  276.                     else if match(s1, '-TOPIC') then
  277.                         listtop := false
  278.                 end
  279.                 else
  280.                     leave;
  281.             until false;
  282.             s := concat('LIST ', rest);
  283.         end
  284.         else if match(com, 'LEAVE') then
  285.             part
  286.         else if com = 'ME' then begin
  287.             s := concat(CurrentNick, ' ', rest);
  288.             Message(s);
  289.             s := concat('ACTION ', rest);
  290.             sendCTCP(currentTarget, s);
  291.             s := ''
  292.         end
  293.         else if match(com, 'MSG') then begin
  294.             NextArg(rest, s1);
  295.             if IsChannel(s1) then
  296.                 s := concat('> ', s1, ' ', rest)
  297.             else
  298.                 s := concat('> *', s1, '* ', rest);
  299.             ChannelMsg(s1, s);
  300.             s := concat('PRIVMSG ', s1, ' :', rest);
  301.         end
  302.         else if com = 'NOTICE' then begin
  303.             NextArg(rest, s1);
  304.             s := concat('> -', s1, '- ', rest);
  305.             ChannelMsg(s1, s);
  306.             s := concat('NOTICE ', s1, ' :', rest)
  307.         end
  308.         else if match(com, 'NOTIFY') then begin
  309.             DoNotify(rest);
  310.             s := ''
  311.         end
  312.         else if match(com, 'QUERY') then begin
  313.             if rest = '' then begin
  314.                 if lastMSG <> '' then
  315.                     dd := DoJoin(lastMSG)
  316.             end
  317.             else
  318.                 dd := DoJoin(rest);
  319.             s := ''
  320.         end
  321.         else if match(com, 'QUIT') then
  322.             signoff
  323.         else if com = 'QUOTE' then
  324.             s := rest
  325.         else if match(com, 'SERVER') then begin
  326.             s := '';
  327.             DoServer(rest);
  328.         end
  329.         else if match(com, 'SIGNOFF') then
  330.             signoff
  331.         else if match(com, 'SQUIT') then
  332.             twoargs('SQUIT')
  333.         else if match(com, 'TOPIC') then
  334.             twoargs('TOPIC')
  335.         else if match(com, 'TYPE') then begin
  336.             i := ApplCoroutine(@TypeCmd, COSPACE);
  337.             s := ''
  338.         end
  339.         else if com = 'VERSION' then begin
  340.             if rest[0] = chr(0) then begin
  341.                 s := concat('Client is ircle ', CL_VERSION);
  342.                 Message(s);
  343.             end;
  344.             s := concat('VERSION ', rest);
  345.         end
  346.         else if (com = 'WHO') or (com = 'NAMES') then begin
  347.             if rest[0] = chr(0) then
  348.                 if CurrentTarget[0] <> chr(0) then
  349.                     s := concat(com, ' ', CurrentTarget);
  350.         end
  351.         else if match(com, 'WHOIS') then begin
  352.             if rest = '' then
  353.                 s := concat('WHOIS ', lastMSG)
  354.             else
  355.                 s := concat('WHOIS ', rest);
  356.         end;
  357.     end;
  358.  
  359.  
  360. procedure sendCTCP (var t, s: string);
  361.     var
  362.         i: integer;
  363.         com: str255;
  364.     begin
  365.         if serverStatus = 0 then begin
  366.             i := pos(' ', s);
  367.             if i = 0 then begin
  368.                 com := s;
  369.                 s := ''
  370.             end
  371.             else begin
  372.                 com := copy(s, 1, i - 1);
  373.                 delete(s, 1, i);
  374.             end;
  375.             UprString(com, false);
  376.             s := concat('PRIVMSG ', t, ' :', chr(1), com, ' ', s, chr(1));
  377.             PutLine(s);
  378.         end
  379.         else
  380.             StatusMsg(E_NOSERVER);
  381.     end;
  382.  
  383. procedure HandleCommand (var s: string);
  384.     begin
  385.         if serverStatus = 0 then begin
  386.             flushing := false;
  387.             UpdateStatusLine;
  388.             TranslateCommand(s);
  389.             if s <> '' then begin
  390.                 PutLine(s);
  391.                 s := ''
  392.             end
  393.         end
  394.         else
  395.             StatusMsg(E_NOSERVER);
  396.     end;
  397.  
  398. procedure RegUser;
  399.     var
  400.         s0, s: string;
  401.         i: integer;
  402.     begin
  403.         SetMainTitle(CurrentNick);
  404.         CurrentServer := ''; { server will respond with NOTICE }
  405.         serverVersion := SV_27; { others will generate specific responses }
  406.         s := concat('NICK ', currentNick);
  407.         HandleCommand(s);
  408.         s0 := default^^.userLoginName;
  409.         i := pos('@', s0);
  410.         if i > 0 then
  411.             s := concat('USER ', copy(s0, 1, i - 1), ' ', copy(s0, i + 1, 255), ' . :', default^^.username)
  412.         else
  413.             s := concat('USER ', s0, ' . . :', default^^.username);
  414.         HandleCommand(s);
  415.         s0 := default^^.autoExec;
  416.         while s0 <> '' do begin
  417.             i := pos(';', s0);
  418.             if i = 0 then
  419.                 i := 255;
  420.             s := copy(s0, 1, i - 1);
  421.             HandleCommand(s);
  422.             delete(s0, 1, i)
  423.         end;
  424.         GetAllWindows(true, false, false, s0);
  425.         if s0[0] <> chr(0) then begin
  426.             s := concat('JOIN :', s0);
  427.             HandleCommand(s)
  428.         end;
  429.     end;
  430.  
  431. end.